#include "PANEApp.h"
namespace PANEApp {

struct MyVideoTraceApp::Imp {

};

MyVideoTraceApp::MyVideoTraceApp()
: windowName_("")
, windowStatus_(0)
, imgBuffer_(NULL)
{
}

MyVideoTraceApp::~MyVideoTraceApp() {
	if( NULL != imgBuffer_ ) cvReleaseImage( &imgBuffer_ );
}

void MyVideoTraceApp::createWindow(string windowName) {
	windowName_ = windowName;

	windowStatus_ = cvNamedWindow(getWindowName().c_str(), CV_WINDOW_AUTOSIZE);
	cvMoveWindow(getWindowName().c_str(), 100, 100);
	bindMouseEvents();
}

void MyVideoTraceApp::bindMouseEvents() {
	MouseEventManagerSingleton::Instance().setApp( this );
	cvSetMouseCallback( windowName_.c_str(), MouseEventManager::on_mouse, this );
}

void MyVideoTraceApp::destroyWindow() {
	cvDestroyWindow(getWindowName().c_str());
	windowStatus_ = 0;
}

string MyVideoTraceApp::getWindowName() const {
	return windowName_;
}

bool MyVideoTraceApp::isWindowCreated() const {
	return 1 == windowStatus_;
//	return NULL != cvGetWindowHandle( getWindowName().c_str() );
}

Document * MyVideoTraceApp::createDocument( string filename ) {
	// TODO
	updateView();
	return DocumentPtr::GetPointer( doc_ );
}

void MyVideoTraceApp::setDocument( DocumentPtr doc ) {
	doc_ = doc;
}

Document * MyVideoTraceApp::getDocument() {
	return DocumentPtr::GetPointer( doc_ );
}


void MyVideoTraceApp::fetchEvents() {
	cvWaitKey( 1 );
}

void MyVideoTraceApp::createImageBuffer() {
	if( NULL != imgBuffer_ ) cvReleaseImage( &imgBuffer_ );

	PANEElement * const firstElem = dynamic_cast< PANEElement * >( getDocument()->getFirstChild() );
	if( NULL == firstElem ) return;

	const unsigned long width = firstElem->getWidth();
	const unsigned long height = firstElem->getHeight();

	imgBuffer_ = cvCreateImage( cvSize( (int) width, (int) height), IPL_DEPTH_8U, 3);
}

void MyVideoTraceApp::updateView() {
	if( NULL == imgBuffer_ ) createImageBuffer();

	DocumentTraversal * const dt = dynamic_cast< DocumentTraversal *>( getDocument() );
	NodeIterator * const iter = dt->createNodeIterator( getDocument()->getFirstChild(), NodeFilter::SHOW_ELEMENT, NULL, false );

	for( Node * node = NULL; NULL != (node = iter->nextNode()); ) {
		dynamic_cast< RenderableWithOpenCV * >( node )->render( imgBuffer_ );
	}

	cvShowImage( getWindowName().c_str(), imgBuffer_ );
}

void MyVideoTraceApp::setDataFile(string dataFileName) {
	dataFileName_ = dataFileName;
}

string MyVideoTraceApp::getDataFile() const {
	return dataFileName_;
}

}
